openapi: 3.1.0
info:
  title: クラウドストレージ Open API
  description: >
    MoreLogin Open API から MoreLogin のクラウドストレージのファイル、アップロード、削除、ファイルラベルを管理します。


    **ベース URL**：`https://api.morelogin.com`


    認証は OAuth2
    ベアラートークンで行います。詳細は[認証](../Getting%20Started/authentication.md)を参照してください。
  version: '2026-09-05'
servers:
  - url: https://api.morelogin.com
tags:
  - name: Cloud Storage
    description: ストレージ容量と使用量を照会
  - name: Cloud Storage Files
    description: クラウドストレージファイルの照会、アップロード、削除
  - name: Cloud Storage File Tags
    description: クラウドストレージファイルに付与されたタグを管理
x-tagGroups:
  - name: Cloud Storage
    tags:
      - Cloud Storage
      - Cloud Storage Files
      - Cloud Storage File Tags
paths:
  /cloudstorage/info:
    get:
      summary: クラウドストレージ情報を照会
      description: >-
        チームのクラウドストレージ容量と現在の使用量を返します。

        -
        **前提条件**：チームにクラウドストレージのレコードが既に存在すること。**クラウドストレージを一度も契約していないチームには、容量ゼロではなくエラーが返ります**
        — このレコードはストレージ購入時に作成され、本エンドポイントが遅延作成することはありません。

        - **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。

        - **単位**：`capacity` と `usedCapacity` はバイト数です。

        - **精度**：`usedCapacity`
        はアップロードと削除の際に維持される累積カウンターで、ファイルテーブルを都度合計した値ではありません。そのため
        `/cloudstorage/file/page` の `fileSize` の合計とずれることがあります。

        - **値**：`capacityStatus` は容量が正の値で使い切られている場合にのみ `1` になります。`isExpired`
        は有効期限を現在時刻と比較します。アップロードが確定していないファイルは `usedCapacity` に計上されません。


        文書化されたビジネスエラー: `39001`。 各コードの意味は [Error
        Codes](../Getting%20Started/error-codes.md)
        を参照してください。どの操作でも共通コードが返る場合があります。
      operationId: queryCloudStorageInfo
      tags:
        - Cloud Storage
      responses:
        '200':
          $ref: '#/components/responses/StorageInfoResponse'
  /cloudstorage/file/page:
    post:
      summary: クラウドストレージファイルをページ照会
      description: >-
        クラウドストレージのファイルをページ単位で一覧します。

        - **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。

        - **可視性**：**アップロードが確定したファイルのみが一覧されます** — 署名付き URL
        を発行したが完了しなかったファイルは現れません。全データ権限を持たないメンバーには、自分がアップロードしたファイルのみが見えます。

        - **フィルタリング**：`fileName` は部分一致、`tagIds` は OR
        一致です。結果は新しい順に並び、この順序は変更できません。

        - **注意**：ファイルに紐付いたままタグが削除された場合、`tagInfo` の要素が null になることがあります。
      operationId: pageCloudStorageFiles
      tags:
        - Cloud Storage Files
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FilePageRequest'
            example:
              pageNo: 1
              pageSize: 20
              fileName: report
              tagIds:
                - '1800000000000001'
      responses:
        '200':
          $ref: '#/components/responses/FilePageResponse'
  /cloudstorage/upload/init:
    post:
      summary: 署名付きアップロード URL を一括発行
      description: >-
        クラウドストレージのレコードを確保し、署名付きアップロード URL を取得します。

        - **前提条件**：チームにクラウドストレージのレコードがあり、期限切れでないこと。ファイル名の基本部分は 60
        文字までで、リクエスト内およびチームの既存ファイル全体に対して一意である必要があります —
        **拡張子を除いた名前で照合される**ため、`a.png` は既存の `a.mp4` と衝突します。

        - **上限**：チーム全体で未確定のアップロードは同時に 100 件までです。

        - **副作用**：ファイル名ごとにアップロード中ステータス・サイズ 0 のレコードを 1 件挿入し、それぞれについて `{id,
        fileName, presignedUrl}` を返します。

        - **容量**：**ここでは空き容量を検証しません。** 容量はアップロード確定時に計上されるため、init が成功しても容量不足で
        complete が失敗し得ます。

        - **完了シグナル**：同期的です。**各署名付き URL の有効期間は 1 時間です**。そこへファイル本体を `PUT`
        した後、`/cloudstorage/upload/complete` を呼び出してください。


        文書化されたビジネスエラー: `39001`, `39037`, `39044`, `39045`, `39047`, `39050`,
        `39051`。 各コードの意味は [Error Codes](../Getting%20Started/error-codes.md)
        を参照してください。どの操作でも共通コードが返る場合があります。
      operationId: batchRequestCloudStoragePresignedUploadUrls
      tags:
        - Cloud Storage Files
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UploadInitRequest'
            example:
              fileNames:
                - example.jpg
                - docs/report.pdf
      responses:
        '200':
          $ref: '#/components/responses/UploadInitResponse'
  /cloudstorage/upload/complete:
    post:
      summary: アップロード完了を確認
      description: >-
        アップロード済みのクラウドストレージファイルを確定します。

        - **前提条件**：ファイルのレコードが自チームのものであり、オブジェクトが既にストレージ上にあること — サービスは ETag
        と長さを読み取って検証します。サイズは 0 より大きく 2 GB 未満である必要があります。

        -
        **副作用**：チームのストレージ容量を原子的に計上し、レコードをアップロード済みにして実際のサイズを保存します。これが成功するまで、そのファイルは**`/cloudstorage/file/page`
        に現れず**、100 件の未確定枠のうち 1 つを占有し続けます。

        - **失敗するとアップロード済みオブジェクトは削除されます。**
        早すぎる呼び出し、サイズ上限超過、容量不足のいずれでもストレージから実データが削除され、レコードは未確定のまま残ります。復旧は本エンドポイントのリトライではなく、`/cloudstorage/upload/init`
        からのやり直しと再アップロードです。

        - **完了シグナル**：同期的で、一度成功すれば冪等です — 2 回目の呼び出しは容量を再計上せずに同じファイルを返します。

        - **補足**：確定されないままのレコードは 24 時間後に自動で整理されます。


        文書化されたビジネスエラー: `39001`, `39011`, `39014`, `39041`, `39046`, `39047`。
        各コードの意味は [Error Codes](../Getting%20Started/error-codes.md)
        を参照してください。どの操作でも共通コードが返る場合があります。
      operationId: confirmCloudStorageUploadComplete
      tags:
        - Cloud Storage Files
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UploadCompleteRequest'
            example:
              id: '1800000000000001'
      responses:
        '200':
          $ref: '#/components/responses/UploadCompleteResponse'
  /cloudstorage/file/delete/batch:
    post:
      summary: クラウドストレージファイルを一括削除
      description: >-
        クラウドストレージのファイルを ID で削除します。

        - **前提条件**：すべての ID が自チーム内で解決できること。**ひとつでも解決できなければバッチ全体が拒否されロールバックされます**
        — 既に削除済みの ID も同様です。

        - **副作用**：論理削除です。容量は同一トランザクション内で解放され、保存済みオブジェクトはベストエフォートで削除されます —
        ストレージ側の失敗はログに記録されるだけで呼び出しは失敗しないため、オブジェクトがレコードより長く残ることがあります。タグの紐付けは整理されません。

        - **完了シグナル**：同期的です。解放された容量は `/cloudstorage/info` で確認してください。


        文書化されたビジネスエラー: `39011`。 各コードの意味は [Error
        Codes](../Getting%20Started/error-codes.md)
        を参照してください。どの操作でも共通コードが返る場合があります。
      operationId: batchDeleteCloudStorageFiles
      tags:
        - Cloud Storage Files
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileDeleteRequest'
            example:
              ids:
                - '1800000000001001'
                - '1800000000001002'
      responses:
        '200':
          $ref: '#/components/responses/VoidDataResponse'
  /cloudstorage/file/tag/set:
    post:
      summary: ファイルタグを設定
      description: >-
        クラウドストレージのファイルのタグを置き換えます。

        - **前提条件**：1 回の呼び出しで `fileId` は 1 件、`tagIds`
        は空でなく、自チームのクラウドストレージタグを参照する必要があります。ブラウザープロファイルのタグは拒否されます。

        -
        **副作用**：リクエストに含まれないタグはファイルから外され、含まれていないものは追加されます。空のリストが拒否されるため、**ここですべてのタグを外すことはできません**。

        - **完了シグナル**：同期的で、同一のリクエストボディに対して冪等です。


        文書化されたビジネスエラー: `39011`, `39048`, `39049`。 各コードの意味は [Error
        Codes](../Getting%20Started/error-codes.md)
        を参照してください。どの操作でも共通コードが返る場合があります。
      operationId: setCloudStorageFileTags
      tags:
        - Cloud Storage File Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileTagChangeRequest'
            example:
              fileId: '1800000000001001'
              tagIds:
                - '1800000000000101'
                - '1800000000000102'
      responses:
        '200':
          $ref: '#/components/responses/VoidDataResponse'
  /cloudstorage/file/tag/add:
    post:
      summary: ファイルタグを追加
      description: >-
        既存のタグを外さずに、クラウドストレージのファイルへタグを追加します。

        - **前提条件**：1 回の呼び出しで `fileId` は 1 件、`tagIds`
        は空でなく、自チームのクラウドストレージタグを参照する必要があります。

        - **副作用**：追加のみです。既存のタグはそのまま残ります。置き換えたい場合は set 系のエンドポイントを使ってください。

        - **完了シグナル**：同期的かつ冪等です — 既に付いているタグを追加しても何も変わりません。


        文書化されたビジネスエラー: `39011`, `39048`, `39049`。 各コードの意味は [Error
        Codes](../Getting%20Started/error-codes.md)
        を参照してください。どの操作でも共通コードが返る場合があります。
      operationId: addCloudStorageFileTags
      tags:
        - Cloud Storage File Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileTagChangeRequest'
            example:
              fileId: '1800000000001001'
              tagIds:
                - '1800000000000103'
      responses:
        '200':
          $ref: '#/components/responses/VoidDataResponse'
  /cloudstorage/file/tag/query:
    post:
      summary: ファイルタグを照会
      description: >-
        1 件以上のクラウドストレージファイルに付いているタグを返します。

        - **前提条件**：すべての `fileId` が自チーム内で解決できること。**未知の ID
        がひとつあると呼び出し全体が失敗し**、部分データは返りません。

        - **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。

        - **注意**：`tagIds` は紐付けから読まれる一方、タグの詳細は現存するタグから取得されるため、紐付いたまま削除されたタグは
        `tagIds` に現れるのに詳細側に対応する要素がありません。両者の長さは一致しないことがあります。
      operationId: queryCloudStorageFileTags
      tags:
        - Cloud Storage File Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileTagQueryRequest'
            example:
              fileIds:
                - '1800000000001001'
      responses:
        '200':
          $ref: '#/components/responses/FileTagsResponse'
  /cloudstorage/tag/all:
    get:
      summary: クラウドストレージのファイルタグをすべて照会
      description: >-
        チーム内のすべてのクラウドストレージファイルタグを返します。

        - **副作用**：なし。読み取り専用。バックオフを入れれば安全にリトライできます。

        -
        **補足**：ページングはなく、クラウドストレージのタグにはサーバー側の件数上限がないため、レスポンスはチームが作成したタグ数に応じて大きくなります。
      operationId: queryAllCloudStorageFileTags
      tags:
        - Cloud Storage File Tags
      responses:
        '200':
          $ref: '#/components/responses/TagListResponse'
  /cloudstorage/tag/create:
    post:
      summary: クラウドストレージのファイルタグを作成
      description: >-
        クラウドストレージのファイルタグを作成します。

        - **前提条件**：`tagName` は空白であってはなりません。

        -
        **副作用**：固定パレットから選ばれた色でタグを作成します。**名前の重複チェックはなく、件数上限もありません**。したがって呼び出しを繰り返すと同名のタグが
        2 件作られます。

        - **完了シグナル**：同期的です。レスポンスに新しいタグが入ります。
      operationId: createCloudStorageFileTag
      tags:
        - Cloud Storage File Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TagCreateRequest'
            example:
              tagName: Invoice
      responses:
        '200':
          $ref: '#/components/responses/TagResponse'
  /cloudstorage/tag/edit:
    post:
      summary: クラウドストレージのファイルタグを編集
      description: |-
        クラウドストレージのファイルタグをリネームします。
        - **前提条件**：タグが自チーム内に存在し、クラウドストレージのタグであること。
        - **副作用**：名前のみが変わります。色と既存のすべての紐付けは保持されるため、ファイルには即座に新しい名前が表示されます。
        - **完了シグナル**：同期的です。楽観ロックはないため、同時リネームは後書き優先になります。
      operationId: editCloudStorageFileTag
      tags:
        - Cloud Storage File Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TagEditRequest'
            example:
              id: '1800000000000101'
              tagName: Invoice 2026
      responses:
        '200':
          $ref: '#/components/responses/BooleanDataResponse'
  /cloudstorage/tag/delete/batch:
    post:
      summary: クラウドストレージのファイルタグを削除
      description: >-
        クラウドストレージのファイルタグを削除します。

        - **前提条件**：すべての ID が自チームのクラウドストレージタグであること。**無効な ID がひとつあるとバッチ全体が失敗します**。

        - **副作用**：タグは削除されますが、**ファイルへの紐付けは整理されません**。想定される影響は 2
        つです。`/cloudstorage/file/tag/query` が削除済みタグ ID
        を詳細なしで返し続けること、`/cloudstorage/file/page` の `tagInfo` に null
        要素が含まれ得ることです。削除済みタグ ID でファイルを絞り込むと何も返りません。

        - **完了シグナル**：同期的で、トランザクションで包まれていません。
      operationId: deleteCloudStorageFileTags
      tags:
        - Cloud Storage File Tags
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TagDeleteRequest'
            example:
              ids:
                - '1800000000000101'
                - '1800000000000102'
      responses:
        '200':
          $ref: '#/components/responses/BooleanDataResponse'
components:
  securitySchemes:
    Authorization:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    ApiResponseBase:
      type: object
      properties:
        code:
          type: integer
          description: 結果コード。`0` は成功を意味し、それ以外は異常を示します。
          example: 0
        msg:
          type:
            - string
            - 'null'
          description: エラーメッセージ。
          example: null
        requestId:
          type: string
          description: 操作リクエスト ID。リクエストが API ゲートウェイを経由した場合に付与されることがあります。
          example: 1d4f3ea968664593860b94b35d4ebf5e
      required:
        - code
        - msg
    StorageInfo:
      type: object
      properties:
        capacity:
          type: string
          description: クラウドストレージの総容量（バイト）。
          example: '10737418240'
        usedCapacity:
          type: string
          description: クラウドストレージの使用容量（バイト）。
          example: '536870912'
        expireDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
          description: クラウドストレージの有効期限。
        capacityStatus:
          type: integer
          description: 容量ステータス：0 = 正常、1 = 満杯。
          example: 0
        isExpired:
          type: boolean
          description: サブスクリプションプランが期限切れかどうか。
          example: false
    CloudStorageFile:
      type: object
      properties:
        id:
          type: string
          description: クラウドストレージのファイル ID。
          example: '1800000000001001'
        fileName:
          type: string
          description: ファイル名（拡張子なし）。
          example: example
        fileExt:
          type: string
          description: 拡張子。
          example: jpg
        fileSize:
          type: string
          description: ファイルサイズ（バイト）。
          example: '204800'
        fileType:
          type: integer
          description: ファイル種別：0 = 画像、1 = 動画、2 = アプリケーション、3 = 音声、4 = ドキュメント、5 = その他。
          example: 0
        tagInfo:
          type: array
          description: ファイルに付いているタグの詳細。
          items:
            $ref: '#/components/schemas/TagInfo'
        createDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
          description: アップロード日時。
        updateDate:
          type: string
          pattern: ^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$
          description: 更新日時。
    TagInfo:
      type: object
      properties:
        id:
          type: string
          description: タグ ID。
          example: '1800000000000101'
        tagSource:
          type: string
          description: タグのソース。例：ENV、PROXY。
          example: ENV
        tagName:
          type: string
          description: タグ名。
          example: Invoice
        tagType:
          type: string
          description: タグ種別：TAG または GROUP。
          example: TAG
        tagIcon:
          type: string
          description: タグのアイコン。
          example: ''
    FilePageRequest:
      type: object
      properties:
        pageNo:
          type: integer
          description: 現在のページ番号。1 から始まります。デフォルトは 1 です。
          minimum: 1
          default: 1
          example: 1
        pageSize:
          type: integer
          description: 1 ページあたりの件数。デフォルトは 10 です。
          minimum: 1
          default: 10
          example: 20
        fileName:
          type: string
          description: あいまい検索用のファイル名キーワード。
          example: report
        tagIds:
          type: array
          description: タグ ID でファイルを絞り込みます。
          items:
            type: string
          example:
            - '1800000000000101'
        fileType:
          type: integer
          description: ファイル種別フィルター：0 = 画像、1 = 動画、2 = アプリケーション、3 = 音声、4 = ドキュメント、5 = その他。
          example: 0
        fileIds:
          type: array
          description: ファイル ID でファイルを絞り込みます。
          items:
            type: string
          example:
            - '1800000000001001'
    FilePageData:
      type: object
      properties:
        current:
          type: string
          example: '1'
        pages:
          type: string
          example: '7'
        total:
          type: string
          example: '128'
        dataList:
          type: array
          items:
            $ref: '#/components/schemas/CloudStorageFile'
      required:
        - current
        - pages
        - total
        - dataList
    UploadInitRequest:
      type: object
      properties:
        fileNames:
          type: array
          minItems: 1
          description: アップロードするファイル名の一覧（拡張子あり）。例：photo.jpg、video.mp4。
          items:
            type: string
          example:
            - photo.jpg
            - video.mp4
      required:
        - fileNames
    UploadInitResult:
      type: object
      properties:
        id:
          type: string
          description: クラウドストレージのファイル ID。
          example: '1800000000000001'
        fileName:
          type: string
          description: ファイル名（拡張子あり）。
          example: photo.jpg
        presignedUrl:
          type: string
          description: S3 の署名付きアップロード URL。HTTPS PUT でファイル本体をアップロードしてください。
          example: https://example.com/presigned-upload-url
    UploadCompleteRequest:
      type: object
      properties:
        id:
          type: string
          description: 署名付きアップロード URL の API が返したクラウドストレージのファイル ID。
          example: '1800000000000001'
      required:
        - id
    FileDeleteRequest:
      type: object
      properties:
        ids:
          type: array
          minItems: 1
          items:
            type: string
          description: 削除するクラウドストレージのファイル ID。
          example:
            - '1800000000001001'
            - '1800000000001002'
      required:
        - ids
    FileTagChangeRequest:
      type: object
      properties:
        fileId:
          type: string
          description: クラウドストレージのファイル ID。
          example: '1800000000001001'
        tagIds:
          type: array
          minItems: 1
          items:
            type: string
          description: タグ ID の一覧。
          example:
            - '1800000000000101'
            - '1800000000000102'
      required:
        - fileId
        - tagIds
    FileTagQueryRequest:
      type: object
      properties:
        fileIds:
          type: array
          minItems: 1
          items:
            type: string
          description: クラウドストレージのファイル ID。
          example:
            - '1800000000001001'
      required:
        - fileIds
    FileTagResultData:
      type: object
      properties:
        fileId:
          type: string
          description: クラウドストレージのファイル ID。
          example: '1800000000001001'
        tagIds:
          type: array
          items:
            type: string
          description: ファイルに付いているタグ ID。
          example:
            - '1800000000000101'
        tagInfo:
          type: array
          description: タグの詳細。
          items:
            $ref: '#/components/schemas/TagInfo'
    TagCreateRequest:
      type: object
      properties:
        tagName:
          type: string
          description: タグ名。
          example: Invoice
      required:
        - tagName
    TagEditRequest:
      type: object
      properties:
        id:
          type: string
          description: タグ ID。
          example: '1800000000000101'
        tagName:
          type: string
          description: タグ名。
          example: Invoice 2026
      required:
        - id
        - tagName
    TagDeleteRequest:
      type: object
      properties:
        ids:
          type: array
          minItems: 1
          items:
            type: string
          description: 削除するタグ ID。
          example:
            - '1800000000000101'
      required:
        - ids
  responses:
    StorageInfoResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    $ref: '#/components/schemas/StorageInfo'
                required:
                  - data
    FilePageResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    $ref: '#/components/schemas/FilePageData'
                required:
                  - data
    UploadInitResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/UploadInitResult'
                required:
                  - data
    UploadCompleteResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CloudStorageFile'
                required:
                  - data
    VoidDataResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    type: 'null'
                    example: null
    BooleanDataResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    type: boolean
                    example: true
                required:
                  - data
    FileTagsResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/FileTagResultData'
                required:
                  - data
    TagListResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/TagInfo'
                required:
                  - data
    TagResponse:
      description: 成功
      content:
        application/json:
          schema:
            allOf:
              - $ref: '#/components/schemas/ApiResponseBase'
              - type: object
                properties:
                  data:
                    $ref: '#/components/schemas/TagInfo'
                required:
                  - data
security:
  - Authorization: []
